﻿using System;
using System.ComponentModel;

namespace Rosetta.Composition
{
    public sealed class NodeConnection : IDisposable, INotifyPropertyChanged
    {
        // TODO: Load from xml file

        #region Fields

        private bool _HasMultipleResults;

        #endregion

        #region Events

        public event PropertyChangedEventHandler PropertyChanged;

        #endregion

        #region Constructors

        internal NodeConnection(Node beginPoint, Node endPoint, int argumentIndex, bool hasMultipleResults)
        {
            BeginPoint = beginPoint;
            EndPoint = endPoint;
            ArgumentIndex = argumentIndex;
            CanHaveMultipleResults = hasMultipleResults;
            HasMultipleResults = hasMultipleResults;
        }

        #endregion

        #region Public Properties

        public int ArgumentIndex { get; private set; }

        [NotNull]
        public Node BeginPoint { get; private set; }

        public bool CanHaveMultipleResults { get; private set; }

        [NotNull]
        public Node EndPoint { get; private set; }

        public bool HasMultipleResults
        {
            get
            {
                return _HasMultipleResults;
            }
            set
            {
                if (!CanHaveMultipleResults && value)
                {
                    throw new InvalidOperationException("NodeConnection can't have multiple results.");
                }

                if (_HasMultipleResults != value)
                {
                    _HasMultipleResults = value;
                    SendPropertyChanged("HasMultipleResults");
                }
            }
        }

        #endregion

        #region Public Methods

        public void Dispose()
        {
// ReSharper disable AssignNullToNotNullAttribute
            BeginPoint = null;
// ReSharper disable ConditionIsAlwaysTrueOrFalse
            if (EndPoint != null)
// ReSharper restore ConditionIsAlwaysTrueOrFalse
            {
                EndPoint.Dispose();
                EndPoint = null;
// ReSharper restore AssignNullToNotNullAttribute
            }
        }

        #endregion

        #region Private Methods

        private void SendPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }

        #endregion
    }
}